/*
 * ads1115.c
 *
 *  Created on: Aug 30, 2020
 *      Author: daniel
 */

#include "ads1115.h"


extern I2C_HandleTypeDef hi2c1;

#define ADS1115_I2C		hi2c1
#define ADS1115_ADDR	0x48

// ---------------------------------------------
// ADS1115_ReadRegisters
// ---------------------------------------------
bool ADS1115_ReadRegisters(uint8_t address, uint8_t *data, uint8_t size) {
//	HAL_StatusTypeDef 	status = 0;

	return (HAL_I2C_Mem_Read(&ADS1115_I2C, ADS1115_ADDR<<1, address, I2C_MEMADD_SIZE_8BIT, data, size, 100) == HAL_OK);

//	status = 0;
}

// ---------------------------------------------
// ADS1115_WriteRegisters
// ---------------------------------------------
bool ADS1115_WriteRegisters(uint8_t *data, uint8_t size) {
    return (HAL_I2C_Master_Transmit(&ADS1115_I2C, ADS1115_ADDR<<1, data, size, 100) == HAL_OK);
}

//uint16_t ADS1115_ReadADC(uint8_t channel) {
//
//	if (channel > 3) {
//		return 0;
//	}
//
//	uint16_t register_data = 0;
//	int16_t received_data = 0;
//	uint8_t data[3] = {0};
//
//	register_data = ADS1115_COMP_QUE;						// 11  : Disable comparator and set ALERT/RDY pin to high-impedance (default)
//	register_data |= ADS1115_DR_2;							// 100 : 128 SPS (default)
//	register_data |= ADS1115_MODE;							// 1   : Single-shot mode or power-down state (default)
//	register_data &= ~ADS1115_PGA;							// 000 : FSR = ±6.144 V (187.5μV)
//	register_data |= ADS1115_PGA_1;							// 010 : FSR = 2.048 (62.5uV)
//	switch (channel) {
//	case 0:
//		register_data |= ADS1115_MUX_2;						// 100 : AINP = AIN0 and AINN = GND
//		break;
//	case 1:
//		register_data |= (ADS1115_MUX_2 | ADS1115_MUX_0);	// 101 : AINP = AIN1 and AINN = GND
//		break;
//	case 2:
//		register_data |= (ADS1115_MUX_2 | ADS1115_MUX_1);	// 110 : AINP = AIN2 and AINN = GND
//		break;
//	case 3:
//		register_data |= ADS1115_MUX;						// 111 : AINP = AIN3 and AINN = GND
//		break;
//	}
//	register_data |= ADS1115_OS;							// 1   : Start a single conversion (when in power-down state)
//
//	data[0] = ADS1115_REG_CONFIG;
//	data[1] = register_data >> 8;							// msb
//	data[2] = register_data & 0xFF;							// lsb
//	ADS1115_WriteRegisters(data, 3);
//
//	// TODO: 需要变换为异步启动和读取
//	HAL_Delay(10);										// maximum time = 1 / (0.9 * 128SPS) + 30us = ~8ms
//
//	ADS1115_ReadRegisters(ADS1115_REG_CONVERSION, data, 2);
//
//	received_data = (int16_t)((data[0] << 8) | data[1]);
//
//	if (received_data < 0) {
//		received_data = 0;
//	}
//
//	return received_data;
//}

//float ADS1115_Read(uint8_t channel) {
//
//	return (float)ADS1115_ReadADC(channel) * 62.5 / 1000000.0;		// FSR = ±2.048(62.5uV)
//}

bool ADS1115_Start(uint8_t channel)
{
	if (channel > 3) {
		return false;
	}

	uint16_t register_data = 0;
	uint8_t data[3] = {0};

	register_data = ADS1115_COMP_QUE;						// 11  : Disable comparator and set ALERT/RDY pin to high-impedance (default)
	register_data |= ADS1115_DR_2;							// 100 : 128 SPS (default)
	register_data |= ADS1115_MODE;							// 1   : Single-shot mode or power-down state (default)
	register_data &= ~ADS1115_PGA;							// 000 : FSR = ±6.144 V (187.5μV)
	register_data |= ADS1115_PGA_1;							// 010 : FSR = 2.048 (62.5uV)
	switch (channel) {
	case 0:
		register_data |= ADS1115_MUX_2;						// 100 : AINP = AIN0 and AINN = GND
		break;
	case 1:
		register_data |= (ADS1115_MUX_2 | ADS1115_MUX_0);	// 101 : AINP = AIN1 and AINN = GND
		break;
	case 2:
		register_data |= (ADS1115_MUX_2 | ADS1115_MUX_1);	// 110 : AINP = AIN2 and AINN = GND
		break;
	case 3:
		register_data |= ADS1115_MUX;						// 111 : AINP = AIN3 and AINN = GND
		break;
	}
	register_data |= ADS1115_OS;							// 1   : Start a single conversion (when in power-down state)

	data[0] = ADS1115_REG_CONFIG;
	data[1] = register_data >> 8;							// msb
	data[2] = register_data & 0xFF;							// lsb

	return ADS1115_WriteRegisters(data, 3);
}

bool ADS1115_Read(uint16_t* value)
{
	int16_t received_data = 0;
	uint8_t data[2] = {0};
	float	mv;

	if (!ADS1115_ReadRegisters(ADS1115_REG_CONVERSION, data, 2)) {
		return false;
	}

	received_data = (int16_t)((data[0] << 8) | data[1]);

	if (received_data < 0) {
		received_data = 0;
	}

	mv = (float)received_data * 62.5 / 1000.0;		// FSR = ±2.048(62.5uV)

	*value = (mv < 0) ? 0 : (uint16_t)mv;

	return true;
}

